using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ThridGroup.ERP.Application.Contracts.ProductionSystem;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using ThridGroup.ERP.ProductionSystem;
using ThridGroup.ERP.Application.Contracts.DTO;

namespace ThridGroup.ERP.Application.ProductionSystem
{
    public class OutgoingInspectionService : ApplicationService, IOutgoingInspectionService
    {
        private readonly IRepository<OutgoingInspection, int> _outgoingInspectionRepository;
        private readonly ILogger<OutgoingInspectionService> _logger;

        public OutgoingInspectionService(
            IRepository<OutgoingInspection, int> outgoingInspectionRepository,
            ILogger<OutgoingInspectionService> logger)
        {
            _outgoingInspectionRepository = outgoingInspectionRepository;
            _logger = logger;
        }

        /// <summary>
        /// 添加出货检验
        /// </summary>
        public async Task<int> AddOutgoingInspection(OutgoingInspectionDto dto)
        {
            try
            {
                _logger.LogInformation($"开始添加出货检验：Code={dto.OutgoingCode}, Name={dto.OutgoingName}");

                // 验证输入
                ValidateOutgoingInspectionInput(dto);
                
                // 记录所有字段的值，便于调试
                _logger.LogInformation($"出货检验字段值: " +
                    $"OutgoingCode={dto.OutgoingCode}, " +
                    $"OutgoingName={dto.OutgoingName}, " +
                    $"Customer={dto.Customer}, " +
                    $"ProductCode={dto.ProductCode}, " +
                    $"ProductName={dto.ProductName}");

                // 创建新实体
                var entity = new OutgoingInspection
                {
                    OutgoingCode = dto.OutgoingCode,
                    OutgoingName = dto.OutgoingName,
                    Customer = dto.Customer ?? string.Empty,
                    Batch = dto.Batch ?? string.Empty,
                    ProductCode = dto.ProductCode ?? string.Empty,
                    ProductName = dto.ProductName ?? string.Empty,
                    Specifications = dto.Specifications ?? string.Empty,
                    Unitt = dto.Unitt ?? string.Empty,
                    Send = dto.Send,
                    TestingNum = dto.TestingNum,
                    UnqualifiedNum = dto.UnqualifiedNum,
                    TestingResult = dto.TestingResult ?? string.Empty,
                    ShipmentDate = dto.ShipmentDate,
                    TestingDate = dto.TestingDate,
                    TestingPerson = dto.TestingPerson ?? string.Empty,
                    State = dto.State
                    // Remarks = dto.Remarks ?? string.Empty // 暂时注释，待添加数据库字段后启用
                };

                _logger.LogInformation($"准备插入数据库：Code={entity.OutgoingCode}, Name={entity.OutgoingName}");
                
                try
                {
                    // 使用Repository的InsertAsync方法
                    var result = await _outgoingInspectionRepository.InsertAsync(entity, true);
                    
                    // 验证插入后的ID是否有效
                    if (result == null || result.Id <= 0)
                    {
                        throw new Exception("插入成功但未返回有效ID");
                    }
                    
                    _logger.LogInformation($"出货检验添加成功，ID：{result.Id}");
                    return result.Id;
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, $"数据库插入错误：{dbEx.Message}");
                    if (dbEx.InnerException != null)
                    {
                        _logger.LogError($"内部异常：{dbEx.InnerException.Message}");
                        if (dbEx.InnerException.InnerException != null)
                        {
                            _logger.LogError($"内部嵌套异常：{dbEx.InnerException.InnerException.Message}");
                        }
                    }
                    throw new Exception($"数据库操作失败：{dbEx.Message}", dbEx);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加出货检验失败：{ex.Message}");
                throw new Exception($"添加出货检验失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新出货检验
        /// </summary>
        public async Task<int> UpdateOutgoingInspection(OutgoingInspectionDto dto)
        {
            try
            {
                _logger.LogInformation($"开始更新出货检验，ID：{dto.Id}, Code={dto.OutgoingCode}, Name={dto.OutgoingName}");

                // 验证ID
                if (dto.Id <= 0)
                {
                    throw new ArgumentException("无效的出货检验ID");
                }

                // 验证输入
                ValidateOutgoingInspectionInput(dto);
                
                try
                {
                    // 先获取现有实体
                    var entity = await _outgoingInspectionRepository.GetAsync(dto.Id);
                    
                    if (entity == null)
                    {
                        throw new Exception($"未找到ID为{dto.Id}的出货检验");
                    }

                    // 更新实体属性
                    entity.OutgoingCode = dto.OutgoingCode;
                    entity.OutgoingName = dto.OutgoingName;
                    entity.Customer = dto.Customer ?? string.Empty;
                    entity.Batch = dto.Batch ?? string.Empty;
                    entity.ProductCode = dto.ProductCode ?? string.Empty;
                    entity.ProductName = dto.ProductName ?? string.Empty;
                    entity.Specifications = dto.Specifications ?? string.Empty;
                    entity.Unitt = dto.Unitt ?? string.Empty;
                    entity.Send = dto.Send;
                    entity.TestingNum = dto.TestingNum;
                    entity.UnqualifiedNum = dto.UnqualifiedNum;
                    entity.TestingResult = dto.TestingResult ?? string.Empty;
                    entity.ShipmentDate = dto.ShipmentDate;
                    entity.TestingDate = dto.TestingDate;
                    entity.TestingPerson = dto.TestingPerson ?? string.Empty;
                    entity.State = dto.State;
                    // entity.Remarks = dto.Remarks ?? string.Empty; // 暂时注释，待添加数据库字段后启用

                    _logger.LogInformation($"准备更新数据库，ID：{entity.Id}");
                    
                    // 使用Repository的UpdateAsync方法
                    await _outgoingInspectionRepository.UpdateAsync(entity, true);
                    
                    _logger.LogInformation($"出货检验更新成功，ID：{entity.Id}");
                    return entity.Id;
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, $"数据库更新错误：{dbEx.Message}");
                    throw new Exception($"数据库操作失败：{dbEx.Message}", dbEx);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新出货检验失败：{ex.Message}");
                throw new Exception($"更新出货检验失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 删除出货检验
        /// </summary>
        public async Task DeleteOutgoingInspection(int id)
        {
            try
            {
                _logger.LogInformation($"开始删除出货检验，ID：{id}");

                // 验证ID
                if (id <= 0)
                {
                    throw new ArgumentException("无效的出货检验ID");
                }

                try
                {
                    // 先获取现有实体
                    var entity = await _outgoingInspectionRepository.GetAsync(id);
                    
                    if (entity == null)
                    {
                        throw new Exception($"未找到ID为{id}的出货检验");
                    }

                    // 直接进行物理删除
                    _logger.LogInformation($"准备删除数据库记录，ID：{id}");
                    
                    await _outgoingInspectionRepository.DeleteAsync(id, true);
                    
                    _logger.LogInformation($"出货检验删除成功，ID：{id}");
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, $"数据库删除错误：{dbEx.Message}");
                    throw new Exception($"数据库操作失败：{dbEx.Message}", dbEx);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除出货检验失败：{ex.Message}");
                throw new Exception($"删除出货检验失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取单个出货检验
        /// </summary>
        public async Task<OutgoingInspectionDto> GetOutgoingInspection(int id)
        {
            try
            {
                _logger.LogInformation($"开始获取出货检验，ID：{id}");

                if (id <= 0)
                {
                    throw new ArgumentException("无效的出货检验ID");
                }

                var entity = await _outgoingInspectionRepository.GetAsync(id);
                
                if (entity == null)
                {
                    throw new Exception($"未找到ID为{id}的出货检验");
                }

                var dto = MapToDto(entity);
                
                _logger.LogInformation($"成功获取出货检验，ID：{id}");
                
                return dto;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取出货检验失败：{ex.Message}");
                throw new Exception($"获取出货检验失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取所有出货检验
        /// </summary>
        public async Task<List<OutgoingInspectionDto>> GetOutgoingInspections()
        {
            try
            {
                _logger.LogInformation("开始获取出货检验列表");
                
                List<OutgoingInspection> entities;
                
                try
                {
                    // 使用更直接的方式获取数据，避免多层异步嵌套
                    _logger.LogInformation("开始从仓储获取出货检验查询对象");
                    var queryable = await _outgoingInspectionRepository.GetQueryableAsync();
                    _logger.LogInformation("成功获取查询对象，准备执行ToList查询");
                    
                    entities = await queryable.ToListAsync();
                    _logger.LogInformation($"成功从数据库获取出货检验列表，共{entities.Count}条记录");
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, "数据库查询出货检验列表失败");
                    if (dbEx.InnerException != null)
                    {
                        _logger.LogError($"内部异常：{dbEx.InnerException.Message}");
                        if (dbEx.InnerException.InnerException != null)
                        {
                            _logger.LogError($"二级内部异常：{dbEx.InnerException.InnerException.Message}");
                        }
                    }
                    throw new Exception("数据库查询失败，请检查数据库连接", dbEx);
                }
                
                // 安全处理：如果entities为null，返回空列表
                if (entities == null)
                {
                    _logger.LogWarning("数据库返回的出货检验实体列表为null");
                    return new List<OutgoingInspectionDto>();
                }
                
                // 安全地映射到DTO
                var dtoList = new List<OutgoingInspectionDto>();
                foreach (var entity in entities)
                {
                    try
                    {
                        var dto = MapToDto(entity);
                        if (dto != null)
                        {
                            dtoList.Add(dto);
                        }
                    }
                    catch (Exception mapEx)
                    {
                        _logger.LogError(mapEx, $"映射出货检验实体到DTO失败，ID：{entity.Id}");
                        // 继续处理下一个实体，不中断整个流程
                    }
                }
                
                _logger.LogInformation($"成功获取出货检验列表，共映射{dtoList.Count}条记录");
                
                return dtoList;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取出货检验列表失败：{ex.Message}");
                throw new Exception($"获取出货检验列表失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 验证出货检验输入
        /// </summary>
        private void ValidateOutgoingInspectionInput(OutgoingInspectionDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.OutgoingCode))
            {
                throw new ArgumentException("出货检验单编号不能为空");
            }

            if (string.IsNullOrWhiteSpace(dto.OutgoingName))
            {
                throw new ArgumentException("验单名称不能为空");
            }
        }

        /// <summary>
        /// 映射实体到DTO
        /// </summary>
        private OutgoingInspectionDto MapToDto(OutgoingInspection entity)
        {
            if (entity == null)
            {
                return null;
            }

            return new OutgoingInspectionDto
            {
                Id = entity.Id,
                OutgoingCode = entity.OutgoingCode ?? string.Empty,
                OutgoingName = entity.OutgoingName ?? string.Empty,
                Customer = entity.Customer ?? string.Empty,
                Batch = entity.Batch ?? string.Empty,
                ProductCode = entity.ProductCode ?? string.Empty,
                ProductName = entity.ProductName ?? string.Empty,
                Specifications = entity.Specifications ?? string.Empty,
                Unitt = entity.Unitt ?? string.Empty,
                Send = entity.Send,
                TestingNum = entity.TestingNum,
                UnqualifiedNum = entity.UnqualifiedNum,
                TestingResult = entity.TestingResult ?? string.Empty,
                ShipmentDate = entity.ShipmentDate,
                TestingDate = entity.TestingDate,
                TestingPerson = entity.TestingPerson ?? string.Empty,
                State = entity.State
                // Remarks = entity.Remarks // 暂时注释，待添加数据库字段后启用
            };
        }
    }
} 